package org.example.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import org.example.core.exception.BusinessException;
import org.example.core.web.PageResult;
import org.example.core.web.Result;
import org.example.sys.entity.TSysMenu;
import org.example.sys.entity.TSysRoleMenu;
import org.example.sys.entity.dto.MenuDTO;
import org.example.sys.service.TSysMenuService;
import org.example.sys.service.TSysRoleMenuService;
import org.example.core.utils.BeanConvertUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色菜单管理(TSysRoleMenu)表控制层
 */
@RestController
@RequestMapping("/api/system/roleMenu")
public class TSysRoleMenuController extends ApiController {

    @Resource
    private TSysMenuService menuService;
    @Resource
    private TSysRoleMenuService tSysRoleMenuService;

    @GetMapping
    public Result<PageResult<TSysRoleMenu>> selectAll(Page<TSysRoleMenu> page, TSysRoleMenu tSysRoleMenu) {
        return success(this.tSysRoleMenuService.page(page, new LambdaQueryWrapper<>(tSysRoleMenu)));
    }

    @Operation(summary = "查询角色菜单")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/{id}")
    public Result<List<MenuDTO>> list(@PathVariable("id") Integer roleId) {
        List<TSysMenu> menus = menuService.list(new LambdaQueryWrapper<TSysMenu>().orderByAsc(TSysMenu::getSortNumber));
        List<TSysRoleMenu> roleMenus = tSysRoleMenuService
                .list(new LambdaQueryWrapper<TSysRoleMenu>().eq(TSysRoleMenu::getRoleId, roleId));
        List<MenuDTO> menuDTOList = BeanConvertUtils.convertListTo(menus, MenuDTO::new);
        menuDTOList.forEach(menu -> menu.setChecked(roleMenus.stream()
                .anyMatch(d -> d.getMenuId().equals(menu.getMenuId()))));
        return success(menuDTOList);
    }

    @Operation(summary = "添加或修改角色菜单")
    @Transactional(rollbackFor = {Exception.class})
    @PreAuthorize("hasAuthority('sys:role:update')")
    @PutMapping("/{id}")
    public Result<?> addOrUpdateRoleAuth(@PathVariable("id") Long roleId, @RequestBody List<Long> menuIds) {
        tSysRoleMenuService.remove(new LambdaUpdateWrapper<TSysRoleMenu>().eq(TSysRoleMenu::getRoleId, roleId));
        if (!CollectionUtils.isEmpty(menuIds)) {
            List<TSysRoleMenu> roleMenuList = menuIds.stream()
                    .map(menuId -> new TSysRoleMenu(roleId, menuId))
                    .collect(Collectors.toList());
            if (!tSysRoleMenuService.saveBatch(roleMenuList)) {
                throw new BusinessException("保存失败");
            }
        }
        return success("保存成功");
    }

    @Operation(summary = "移除角色菜单")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @DeleteMapping("/{id}")
    public Result<?> remove(@PathVariable("id") Long roleId, @RequestBody Long menuId) {
        boolean removed = tSysRoleMenuService
                .remove(new LambdaQueryWrapper<TSysRoleMenu>()
                        .eq(TSysRoleMenu::getRoleId, roleId).eq(TSysRoleMenu::getMenuId, menuId));
        return removed ? success() : fail();
    }
}